package cn.tedu.justone.pack01;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ZZ：JustOne
 * VX：Andylau2020smile
 * DY：JustOne2018
 * ZT：《》
 */
public class Demo04_方法示例_tryLock带参 {

    //常用方法四：boolean b = tryLock(long time, TimeUnit unit);
    //常用方法四：boolean b = tryLock(long time, TimeUnit unit);
    //常用方法四：boolean b = tryLock(long time, TimeUnit unit);

    // 1,是tryLock()方法的重载。与其用法类似，即先尝试获取锁，
    //   区别在于这个方法在拿不到锁时会等待一定的时间，
    //   在时间期限之内如果还拿不到锁，就返回false。
    //   如果一开始拿到锁或者在等待期间内拿到了锁，则返回true。
    // 2,本方法在等待时间内可以被打断，
    //   如果被打断就不等了，直接当成没有获取到锁处理。
    //   如果被打断就会抛出异常，所以需要捕捉InterruptedException异常。
    // 3,两个参数分别是时间数据、时间单位。其中时间单位有：
    //   TimeUnit.DAYS-----------天
    //   TimeUnit.HOURS----------时
    //   TimeUnit.MINUTES--------分
    //   TimeUnit.SECONDS--------秒
    //   TimeUnit.MILLISECONDS---毫秒(1000毫秒 = 1秒)
    //   TimeUnit.MICROSECONDS---微秒(1000微秒 = 1毫秒)
    //   ......
    // 4,测试发现，输出"没有获得锁"的语句变少了，因为该线程会等机会。
    //
    public static void main(String[] args) {
        Table03 table = new Table03();

        new Thread("男生"){
            @Override
            public void run() {
                while(table.mi>0){
                    table.foo();
                }
            }
        }.start();

        new Thread("女生"){
            @Override
            public void run() {
                while(table.mi>0){
                    table.foo();
                }
            }
        }.start();
    }
}

class Table03{
    static int mi = 10;
    Lock myLock = new ReentrantLock();
    public void foo(){
        try {
            if(myLock.tryLock(100, TimeUnit.MILLISECONDS)){
                try{
                    String name = Thread.currentThread().getName();
                    System.out.println("获得了锁正在执行核心任务是" + name);
                    mi--;
                    mySleep(10);//故意占用久一点
                }finally {
                    myLock.unlock();//释放锁
                }
            }else{
                String name = Thread.currentThread().getName();
                System.out.println("------没有获得锁，在执行别的任务的" + name);
                mySleep(10);//
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //为了让代码更优雅，编写统一的休眠方法
    public static void mySleep(long m){
        try {
            Thread.sleep(m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
